import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DesktopIcon } from './DeskIcon';
import { IntersectsBox } from './IntersectsBox';
import { deskStore, icons } from './Store';
import "./style.css";

@observer
export class Desktop extends React.Component<{}, {}>{

    @observable selectIng = false;
    ctrl = false;
    shift = false;
    locks: boolean[];

    startX = 1;
    StartY = 1;

    endX = 1;
    endY = 1;

    @observable left = 0;
    @observable top = 0;
    @observable width = 0;
    @observable height = 0;

    ref = React.createRef<HTMLDivElement>();

    @action UpdateSelect()
    {
        this.top = Math.min(this.StartY, this.endY);
        this.left = Math.min(this.startX, this.endX);

        this.width = Math.abs(this.startX - this.endX);
        this.height = Math.abs(this.StartY - this.endY);

        for (let i = 0; i < icons.length; i++)
        {
            let icon = icons[i];
            icon.selected = IntersectsBox(this.left + this.ref.current.scrollLeft, this.top + this.ref.current.scrollTop, this.width, this.height, icon);
            if (this.locks) icon.selected = icon.selected !== this.locks[i];
        }
    }

    componentDidMount()
    {
        window.addEventListener("keydown", this.OnKeyDown);
        window.addEventListener("keyup", this.OnKeyUp);
        window.addEventListener("blur", this.Blur);
    }

    componentWillUnmount()
    {
        window.removeEventListener("keydown", this.OnKeyDown);
        window.removeEventListener("keyup", this.OnKeyUp);
        window.removeEventListener("blur", this.Blur);
    }

    Blur = () =>
    {
        this.ctrl = false;
        this.shift = false;
    };

    OnKeyDown = (e: KeyboardEvent) =>
    {
        this.ctrl = e.ctrlKey;
        this.shift = e.shiftKey;
    };
    OnKeyUp = (e: KeyboardEvent) =>
    {
        this.ctrl = e.ctrlKey;
        this.shift = e.shiftKey;
    };

    PickIcon = action((index: number) =>
    {
        if (this.shift)
        {
            let startIndex = icons.findIndex(icon => icon.selected);
            let lastIndex = -1;
            for (let i = icons.length; i--;)
            {
                if (icons[i].selected)
                {
                    lastIndex = i;
                    break;
                }
            }

            if (index <= startIndex)
            {
                for (let i = startIndex + 1; i < icons.length; i++)
                {
                    if (!icons[i].selected)
                        break;
                    else startIndex = i;
                }
                for (; index < icons.length; index++)
                    icons[index].selected = index <= startIndex;
            }
            else if (index >= lastIndex)
            {
                for (let i = lastIndex; i--;)
                {
                    if (!icons[i].selected)
                        break;
                    else lastIndex = i;
                }
                for (let i = 0; i < icons.length; i++)
                    icons[i].selected = i >= lastIndex && i <= index;
            }
            else
            {
                for (let i = 0; i < icons.length; i++)
                    icons[i].selected = i === index;
            }
        }
        else if (this.ctrl)
        {
            icons[index].selected = !icons[index].selected;
        }
        else
        {
            for (let i = 0; i < icons.length; i++)
                icons[i].selected = i === index;
        }
    });

    render()
    {
        return (
            <div
                style={{
                    backgroundImage: `url(${require("./res/9.jpg").default})`,
                    backgroundSize: "cover",
                    height: "100%",
                }}
            >
                <div
                    style={{
                        //需要左右滚动条时,需要保证整个尺寸
                        position: "absolute",
                        left: 0,
                        top: 0,
                        right: 0,
                        bottom: 0,
                        //
                        overflow: "auto",
                    }}
                    ref={this.ref}
                    onMouseDown={(e: React.MouseEvent<HTMLDivElement, MouseEvent>) =>
                    {
                        (e.target as HTMLDivElement).setPointerCapture(1);
                        action(() =>
                        {
                            this.selectIng = true;
                            this.width = 0;
                            this.height = 0;
                        })();
                        this.startX = e.clientX;
                        this.StartY = e.clientY;
                        this.endX = e.clientX;
                        this.endY = e.clientY;
                        this.locks = (this.ctrl || this.shift) ? icons.map(i => i.selected) : undefined;
                    }}
                    onMouseMove={(e) =>
                    {
                        if (!this.selectIng) return;
                        this.endX = e.clientX;
                        this.endY = e.clientY;
                        this.UpdateSelect();
                    }}
                    onMouseUp={(e) =>
                    {
                        if (!this.selectIng) return;
                        this.selectIng = false;
                        (e.target as HTMLDivElement).releasePointerCapture(1);
                        this.UpdateSelect();
                        this.locks = undefined;
                    }}

                    onDrop={e =>
                    {
                        e.preventDefault();
                        let moveX = e.clientX - deskStore.startX;
                        let moveY = e.clientY - deskStore.startY;
                        action(() =>
                        {
                            for (let icon of icons)
                            {
                                if (icon.selected)
                                {
                                    icon.x += moveX;
                                    icon.y += moveY;
                                }
                            }
                        })();
                    }}

                    onDragOver={e =>
                    {
                        e.preventDefault();
                        e.dataTransfer.dropEffect = "move";
                    }}

                >
                    {icons.map((icon, index) =>
                        <DesktopIcon
                            icon={icon}
                            index={index}
                            OnPick={this.PickIcon}
                        />)
                    }
                </div>
                <div
                    style={{
                        pointerEvents: "none",

                        display: this.selectIng ? "block" : "none",

                        backgroundColor: "#63acff",
                        position: "absolute",
                        border: "1px solid #005ce9",

                        left: this.left,
                        top: this.top,

                        width: this.width,
                        height: this.height,

                        opacity: 0.5
                    }}
                />
            </div>
        );
    }
}

//
let app = document.getElementById("app");
export function RenderDesktop()
{
    ReactDOM.render(<Desktop />, app);
}
